package com.widget;

import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;



import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AbsoluteLayout;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AbsoluteLayout.LayoutParams;

public class NewAppsOnCloud extends Activity {

	private static final int BUFF_LEN = 1024;
	ArrayList<String> packagesOnCloud;
	Map<String,Integer> mapping;
	private CloudHandler mMsgHandler;
	private CloudParser p;
	public AbsoluteLayout ll;
	public AlertDialog.Builder d;
	ScrollView scroll;
	ManageProcess process;
	String path;
	String IP_ADDR;
	String USERNAME;
	String dirComp[];
	int typedTextLength=0;
	EditText et;
	ArrayList<String> actualList=new ArrayList<String>();
	ArrayList<String> searchedList=new ArrayList<String>();
	ArrayList<Integer> indexList=new ArrayList<Integer>();
	ArrayList<String> backUpList=new ArrayList<String>();
	ListView lv;
	ArrayAdapter<String> adapter;
	String[]actualListArray;
	String[]searchArray;
	
	
	
	public int mSelectedRow=0;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
	
		
		super.onCreate(savedInstanceState);
		Bundle bundle = this.getIntent().getExtras();
		path = bundle.getString("PATH");
		IP_ADDR = bundle.getString("IPADDR");
		USERNAME = bundle.getString("USERNAME");
		mMsgHandler = new CloudHandler(this);
		

		et=new EditText(this);
		et.setHint("Search");
		lv=new ListView(this);
		
		packagesOnCloud = new ArrayList<String>();
		String bytesRead = "";
		mapping = new HashMap<String, Integer>();
		process = new ManageProcess();
		process.acquireRoot();
		String outputCmd="";
		String fileList[];
		
		final ProgressDialog dialog = ProgressDialog.show(NewAppsOnCloud.this, "Checking...", 
				"Please wait while I compute the differences. This dialog will " +
				" automatically disappear once the computation is done.", true);
		
		mMsgHandler.setDialog(dialog);
		p = new CloudParser();
		p.setMapper(mapping);
		p.endMatcher(1, mMsgHandler);
		process.setParser(p);
		process.executeCmd(path+" -P  rsync://"+USERNAME+"@"+IP_ADDR+"/"+USERNAME+"/backup/data/app/");
		Log.d("DATAAPPS", "Checking");
		
		ll = new AbsoluteLayout(this);
		
		
        
	}
	
	
	
	
	
	public void absoluteView(){
		PackageManager  pm = getPackageManager();
		List<PackageInfo> pkginfo_list;
		pkginfo_list = pm.getInstalledPackages(PackageManager.GET_ACTIVITIES);
		
		for(int i=0;i<pkginfo_list.size();i++){
			String tDir = pkginfo_list.get(i).applicationInfo.sourceDir;
			//Log.i("Cloud",tDir);
			if(mapping.containsKey(tDir)){
				mapping.put(tDir, new Integer(i));
			}
		}
	
		Set start =mapping.entrySet();
		Iterator iter=start.iterator();
		

				int i=0;
				while(iter.hasNext())
				{
					Log.d("CLOUD", "Displaying Packages not installed");
		            Map.Entry m =(Map.Entry)iter.next();

				
		        	
		        	String tDir = (String) m.getKey();
		        	String dirComp[] = tDir.split("/");
		        	
		        	Log.i("Cloud","extComp:"+tDir.substring(tDir.length()-3, tDir.length()));
		        	if(tDir.length()>4)
		        	{
		        	if((Integer)m.getValue() == 0 && tDir.substring(tDir.length()-3, tDir.length()).equals("apk") ) {
		        		
		        		
		        		Log.d("CLOUD", "Displaying Packages not installed  TDIR :"+tDir+"     DIRComp   : "+dirComp[3]);
		        		if(dirComp[dirComp.length-1].equals("pkg.apk") && dirComp[dirComp.length-2].contains("-"))
		        		{
		        			
		        			
		        			dirComp[dirComp.length-2]=dirComp[dirComp.length-2].substring(0, dirComp[dirComp.length-2].indexOf("-"));
		        			actualList.add(dirComp[dirComp.length-2]);
		        			searchedList.add(dirComp[dirComp.length-2]);
		        			Log.d("FIRST IF CLOUD",dirComp[dirComp.length-2]);
		        			
			        		packagesOnCloud.add(tDir);
				        	
				        	
			        		i++;
		        		}
		        		else if(dirComp[dirComp.length-1].contains("-"))
			        	{
		        			//-2 .apk
		        			
			        		
		        			dirComp[dirComp.length-1]=dirComp[dirComp.length-1].substring(0, dirComp[dirComp.length-1].indexOf("-"));
		        			actualList.add(dirComp[dirComp.length-1]);
		        			searchedList.add(dirComp[dirComp.length-1]);
		        			Log.d("ELSE IF CLOUD",dirComp[dirComp.length-1]);
		        			packagesOnCloud.add(tDir);
				        			        	
			        		i++;
			        	}
		        		
		        	   }

					}
				}
				
				displayOnScreen();

	}
	public void displayOnScreen()
	{
		final AlertDialog.Builder b=new AlertDialog.Builder(this);
		
		actualListArray=new String[actualList.size()];
		for(int i=0;i<actualList.size();i++)
		{
			actualListArray[i]=actualList.get(i);
			//Log.i("Actual List@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@",actualList.get(i));
			backUpList.add(actualListArray[i]);
			searchedList.add(actualList.get(i));
			indexList.add(i);
		}
		
		adapter=new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,actualList);
		lv.setAdapter(adapter);
		lv.setClickable(true);
		
		AbsoluteLayout.LayoutParams  editTextLayout=new AbsoluteLayout.LayoutParams(AbsoluteLayout.LayoutParams.FILL_PARENT, AbsoluteLayout.LayoutParams.WRAP_CONTENT, 0, 0); 
		AbsoluteLayout.LayoutParams  listViewtLayout=new AbsoluteLayout.LayoutParams(AbsoluteLayout.LayoutParams.WRAP_CONTENT, AbsoluteLayout.LayoutParams.WRAP_CONTENT, 0, 50);
		if(actualList.size()==0)
		{
			Toast.makeText(this, "No apps on Cloud", Toast.LENGTH_LONG).show();
			
		}
		else
		{
			
			ll.addView(et, editTextLayout);
			ll.addView(lv, listViewtLayout);
			Toast.makeText(this, "HHEHEH", Toast.LENGTH_LONG).show();
			et.addTextChangedListener(new TextWatcher() {
				
				@Override
				public void onTextChanged(CharSequence s, int start, int before, int count) {
					// TODO Auto-generated method stub
					

					String typedText=et.getText().toString();
					typedTextLength=typedText.length();
					typedText=typedText.toUpperCase();
					searchedList.clear();
					indexList.clear();
					adapter.clear();
					Log.i("FINDING LENGTH", " :   "+actualList.size());
					for(int i=0;i<backUpList.size();i++)
					{
						
						if(typedTextLength<=backUpList.get(i).length())
						{
							
							String temp=backUpList.get(i).toUpperCase();
							Log.i("NEW APPS ON CLOUD  ","   CAME INTO THIS   "+typedText+"   Actual list   "+temp);
							if(temp.contains(typedText))
							{
								indexList.add(i);
								searchedList.add(temp);
								adapter.add(backUpList.get(i));
								Log.i("############## SEARCH LIST ########",backUpList.get(i));
								
							}
						}
					}
					lv.setAdapter(adapter);
					searchArray=new String[searchedList.size()];
					
				}
				
				@Override
				public void beforeTextChanged(CharSequence s, int start, int count,
						int after) {
					// TODO Auto-generated method stub
					
				}
				
				@Override
				public void afterTextChanged(Editable s) {
					// TODO Auto-generated method stub
					
				}
			});
			
		
			lv.setClickable(true);
			lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> arg0, View arg1, final int position,long arg3) 
			{
				
				//String item=(String)lv.getItemAtPosition(position);

				
				b.setTitle("Installtion Entry")
				.setMessage("Do you want to install the apk?")
				.setPositiveButton("Yes", new DialogInterface.OnClickListener() 
				{
					
					@Override
					public void onClick(DialogInterface dialog, int which) 
					{
						final ProgressDialog dialog1 = ProgressDialog.show(NewAppsOnCloud.this, "Download & Install...", 
								"Please wait while I download & install the package. This dialog will " +
								" automatically disappear once the computation is done.", true);
					
					String tmpDir = packagesOnCloud.get(indexList.get(position));
					dirComp = tmpDir.split("/");
				    mMsgHandler.setDialog(dialog1);
					process.setParser(p);
					process.executeCmd(path+" -proguP rsync://"+USERNAME+"@"+IP_ADDR+"/"+USERNAME+"/backup"+tmpDir+" /mnt/sdcard/temp/");
						
					}
				})
				.setNegativeButton("No", new DialogInterface.OnClickListener() {
					
					@Override
					public void onClick(DialogInterface dialog, int which) {
						// TODO Auto-generated method stub
						
					}
				})
				.show();
				
				
				
				

				
			}
		});
		
        setContentView(ll);
		}
	}
	
	public void installApp(){
		InstallParser p1 = new InstallParser();
		p1.endMatcher(1, mMsgHandler);
		process.setParser(p1);
		if(dirComp[1].equals("data") || dirComp[1].equals("system"))
			process.executeCmd("pm install -f /mnt/sdcard/temp/"+dirComp[dirComp.length-1]);
		else
			process.executeCmd("pm install -s /mnt/sdcard/temp/"+dirComp[dirComp.length-1]);
	}
	
	public void syncSystemApps(){
		Log.d("SYSTEMAPPS", "CHECKING :)");
		process.setParser(p);
		process.executeCmd(path+" -P  rsync://"+USERNAME+"@"+IP_ADDR+"/"+USERNAME+"/backup/system/app/");	
	}
	
	public void syncSdCardApps(){
		Log.d("SDCARD", "CHECKING :)");
		process.setParser(p);
		process.executeCmd(path+" -P  rsync://"+USERNAME+"@"+IP_ADDR+"/"+USERNAME+"/backup/mnt/asec/");
		
	}
	private class CloudHandler extends Handler 
	{
		static final int SYNCED=1000;
		static final int UNREACHABLE=1001;
		static final int REFUSED=1002;
		static final int TIMEOUT=1003;
		static final int ERROR=1004;
		static final int DATAAPPS=1007;
		static final int SYSTEMAPPS=1008;
		static final int SDAPPS=1009;
		static final int INSTALLSUCC=1010;
		static final int INSTALLFAIL=1011;

		private Context mContext;
		private ProgressDialog d;
		private AlertDialog.Builder alertDialog;
		public CloudHandler(Context c){
			mContext = c;
			alertDialog = new AlertDialog.Builder(mContext);
		}
		public void setDialog(ProgressDialog dialog){
			d = dialog;
		}
		
		@Override
	    public void handleMessage(Message msg) {
	      	
			if(msg.what == INSTALLSUCC)
			{
				d.dismiss();
				alertDialog.setMessage("Installation Success!!!.");
	      	    alertDialog.setTitle("Notification");
	      	    alertDialog.show();
				
			}
			if(msg.what == INSTALLFAIL)
			{
				d.dismiss();
				alertDialog.setMessage("Installation Failure!!!.");
	      	    alertDialog.setTitle("Notification");
	      	    alertDialog.show();
			}
			if(msg.what == SDAPPS){
				absoluteView();
				d.dismiss();
			}
			if(msg.what == SYSTEMAPPS)
			{
				syncSdCardApps();
			}
			if(msg.what == DATAAPPS)
			{
				syncSystemApps();
			}
	      	if(msg.what == SYNCED)
	      	{
	      		installApp();
	      		//alertDialog.setMessage("Synchronization successfully done!!!");
	      	    //alertDialog.setTitle("Notification");
	      	    //alertDialog.show();
	      	}
	      	if(msg.what == UNREACHABLE)
	      	{
	      		d.dismiss();
	      		alertDialog.setMessage("Network is Unreachable!!!. Please make sure you are connected to Internet.");
	      	    alertDialog.setTitle("Error");
	      	    alertDialog.show();
	      	}
	      	if(msg.what == REFUSED)
	      	{
	      		d.dismiss();
	      		alertDialog.setMessage("Connection Refused!!!. Server might be down.");
	      	    alertDialog.setTitle("Error");
	      	    alertDialog.show();
	      	}
	      	if(msg.what == TIMEOUT)
	      	{
	      		d.dismiss();
	      		alertDialog.setMessage("Connection Timed Out!!!. Please make sure IP is correct.");
	      	    alertDialog.setTitle("Error");
	      	    alertDialog.show();
	      	}
	      	if(msg.what == ERROR)
	      	{
	      		d.dismiss();
	      		/*
	      		alertDialog.setMessage("Sync was not successfull!!!");
	      	    alertDialog.setTitle("Error");
	      	    alertDialog.show();
	      	    */
	      	}
	      
	      
		}

	}

}
